#!/bin/bash
# shellcheck disable=SC2034,SC2317

EXEC_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)

INSTALLER="__INSTALLER__"
BASE_NAME="__BASE_NAME__"
SHA256SUM="__SHA256SUM__"
INSTALLER_MODE="__INSTALLER_MODE__"

export BASE_NAME

ARCHIVE=$(awk '/^__ARCHIVE_BELOW__/ {print NR + 1; exit 0; }' "$0")

INSTALLER_NAME_BASE=$(basename "${BASH_SOURCE[0]}" .run)
INSTALLER_TAR=${INSTALLER_NAME_BASE}.tar.gz
INSTALLER_LOG=${INSTALLER_NAME_BASE}-install.log
INSTALL_LOG=${BASE_NAME}-install.log

# Global Arguments
ARGS_EXTRACT=0
ARGS_EXTRACT_DIR="${EXEC_DIR}/${INSTALLER_NAME_BASE}"

# Window Size
WINDOW_WIDTH=900
WINDOW_HEIGHT=500
WINDOW_ICON=''

TERM_LOCK="/tmp/${INSTALLER}.lock"
if [ "${INSTALLER_MODE}" = "GUI" ] && (! which zenity >/dev/null 2>&1) && [ ! -f "${TERM_LOCK}" ]; then
    if which x-terminal-emulator >/dev/null 2>&1; then
        touch "${TERM_LOCK}"
        x-terminal-emulator --window -e "bash -c \"\"$0\"; rm -f \"${TERM_LOCK}\"; read\""
        exit
    else
        # echo "Cannot find default terminal emulator."
        # echo "Please install x-terminal-emulator or update your alternatives."
        # echo "Alternatively, run this script in GUI mode."
        # echo "Aborting."
        echo "未找到默认终端。"
        echo "请安装 x-terminal-emulator 或更新您的备选器。"
        echo "或者, 在图形模式下运行此脚本。"
        echo "终止。"
        exit
    fi
fi

function GUI_ShowInfo() {
    local Mode=$1
    local InfoType=$2
    local Title=$3
    local Contents=$4

    local MessageType=ERROR
    local ZenityOptions=(
        --width "${WINDOW_WIDTH}"
        --height "${WINDOW_HEIGHT}"
        --title "\"${Title}\""
    )

    case "${InfoType}" in
        info)
            ZenityOptions+=(--info --text "\"${Contents}\"")
            MessageType=INFO
            ;;
        error)
            ZenityOptions+=(--error --text "\"${Contents}\"")
            MessageType=ERROR
            ;;
        text-info)
            ZenityOptions+=(--text-info --filename "\"${Contents}\"")
            MessageType=INFO
            ;;
        *)
            ;;
    esac

    if [ "${Mode}" = "GUI" ] && which zenity >/dev/null 2>&1; then
        eval zenity "${ZenityOptions[*]}" 2>/dev/null || exit $?
    else
        echo "${MessageType}: ${Contents}"
    fi
}

function GUI_ShowProgress() {
    local Mode=$1
    local Title=$2
    local Contents=$3
    local Line Progress Mark

    local ZenityOptions=(
        --width "${WINDOW_WIDTH}"
        --height "${WINDOW_HEIGHT}"
        --title "\"${Title}\""
        --text "\"${Contents}\""
        --progress
        --no-cancel
        --percentage 0
        --auto-close
    )

    if [ "${Mode}" = "GUI" ] && which zenity >/dev/null 2>&1; then
        # echo "Progress: ${Contents}"
        echo "进度: ${Contents}"
        eval zenity "${ZenityOptions[*]}" 2>/dev/null || exit $?
    else
        # echo "Progress: ${Contents}"
        echo "进度: ${Contents}"
        Progress=0
        read -r Line
        while [ -n "${Line}" ] && [ "${Progress}" -le 100 ]; do
            if [ "${Progress}" -eq 0 ] || [ "${Line}" -ge "$((Progress))" ]; then
                Progress=$((Progress + 5))
                if [ "${Progress}" -gt 0 ]; then
                    Mark="##${Mark}"
                fi
                printf "[%-40s] %d%%\r" "${Mark}" "${Progress}"
            fi
            read -r Line
        done
        echo
    fi
}

# Create Temporary Folder
TMPDIR=$(mktemp -d "${EXEC_DIR}/$(basename "$0").XXXXXX")

# Split the script into two parts
# 1. The first part is the code before the __ARCHIVE_BELOW__ marker
# 2. The second part is the code after the __ARCHIVE_BELOW__ marker
# 3. The second part is a tar archive containing the patches and the installer
tail -n+"${ARCHIVE}" "$0" > "${TMPDIR}/${INSTALLER_TAR}"

# Check Sha256Sum
SUM=$(sha256sum "${TMPDIR}/${INSTALLER_TAR}" | awk '{print $1}')
if [ "${SHA256SUM}" != "${SUM}" ]; then
    GUI_ShowInfo "${INSTALLER_MODE}" error "错误" "无效的补丁安装包，SHA256SUM 校验失败！"
    exit 1
fi

while [ -n "$1" ]; do
    case "$1" in
        -e|--extract)
            shift
            ARGS_EXTRACT=1
            ;;
        *)
            ;;
    esac
    shift
done

# Unpack Patches and Installer
# echo "Extracting patches ..."
echo "正在释放补丁 ..."
echo "============================================"
# 50688 = block(512) * 99
BLOCKING_FACTOR=$(gzip --list "${TMPDIR}/${INSTALLER_TAR}" | perl -MPOSIX -ane '$.==2 && print ceil $F[1]/50688')
if [ "${ARGS_EXTRACT}" -eq 1 ]; then
    mkdir -p "${ARGS_EXTRACT_DIR}"
    # shellcheck disable=SC2016
    tar --blocking-factor="${BLOCKING_FACTOR}" \
        --checkpoint=1 --checkpoint-action=exec='echo ${TAR_CHECKPOINT}' \
        -xf "${TMPDIR}/${INSTALLER_TAR}" -C "${ARGS_EXTRACT_DIR}" \
        | GUI_ShowProgress "CLI" "正在释放补丁" "正在释放补丁 ..."
    # Remove Unpacked Folder
    # echo "Clear temp files"
    echo "清理临时文件"
    rm -rf "${TMPDIR}"
    exit 0
else
    # shellcheck disable=SC2016
    tar --blocking-factor="${BLOCKING_FACTOR}" \
        --checkpoint=1 --checkpoint-action=exec='echo ${TAR_CHECKPOINT}' \
        -xf "${TMPDIR}/${INSTALLER_TAR}" -C "${TMPDIR}" \
        | GUI_ShowProgress "${INSTALLER_MODE}" "正在安装补丁" "正在释放补丁 ..."
fi
echo "============================================"

# Check Patch Installer
if [ ! -x "${TMPDIR}/${INSTALLER}" ]; then
    GUI_ShowInfo "${INSTALLER_MODE}" error "错误" "无效的补丁安装包，未找到补丁安装程序！"
    exit 1
fi

# GOTO Unpacked Folder
pushd "${TMPDIR}" > /dev/null || exit $?

# Show Current Path
# echo "Current Path: $(basename "${PWD}")"
echo "当前路径: $(basename "${PWD}")"

# Call Patch Installer
bash "${INSTALLER}"

popd > /dev/null || exit $?

# Copy Installer LogFile
[ -f "${TMPDIR}/${INSTALL_LOG}" ] && cp -a "${TMPDIR}/${INSTALL_LOG}" "${EXEC_DIR}/${INSTALLER_LOG}"

# Remove Unpacked Folder
# echo "Clear temp files"
echo "清理临时文件"
rm -rf "${TMPDIR}"

exit 0

__ARCHIVE_BELOW__
